//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Copyright 2012 Microsoft Corporation. All Rights Reserved
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.   
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

namespace Preflight.Cloud.Push
{
    using System;
    using System.IO;
    using System.Linq;
    using Microsoft.WindowsAzure.ServiceRuntime;
    using ServiceModel.Push;

    public static class RolePreflightCheck
    {
        public const string UnknownRoleName = "UnknownRole";

        public static IDisposable StartPreflightCheck(CloudPushOptions options)
        {
            if (!IsFirstInstance())
            {
                return new NullDisposable();
            }

            var provider = BlobStorageProvider.Create(options.CloudStorageAccount, GetCurrentRoleName());
            return options.Repeat ? InitiateRepeatPush(options, provider) : InitiateOneTimePush(options, provider);
        }

        private static IDisposable InitiateRepeatPush(CloudPushOptions options,  IPreflightCheckRepository provider)
        {
            var pushFactory = PreflightRunnerFactory.Create(options.PreflightContext);
            var repeatPush = pushFactory.CreatePreflightCheckContinuousRunner(provider, options.RepeatInterval);
            repeatPush.Start();
            return repeatPush;
        }

        private static IDisposable InitiateOneTimePush(CloudPushOptions options, IPreflightCheckRepository provider)
        {
            var pushFactory = PreflightRunnerFactory.Create(options.PreflightContext);
            var singlePush = pushFactory.CreatePreflightCheckRunner(provider);
            singlePush.PushPreflightCheckResults();
            return new NullDisposable();
        }

        private static string GetCurrentRoleName()
        {
            return IsRunningInAzure()
                       ? RoleEnvironment.CurrentRoleInstance.Role.Name
                       : UnknownRoleName;
        }

        private static bool IsFirstInstance()
        {
            return 
                IsRunningInAzure() == false ||
                RoleEnvironment.CurrentRoleInstance.Id == RoleEnvironment.CurrentRoleInstance.Role.Instances.First().Id;
        }

        private static bool IsRunningInAzure()
        {
            try
            {
                return RoleEnvironment.CurrentRoleInstance != null;
            }
            catch (InvalidOperationException)
            {
                return false;
            }
            catch (TypeInitializationException)
            {
                return false;
            }
        }

        private class NullDisposable : IDisposable
        {
            public void Dispose()
            {
            }
        }
    }
}
